package com.wolfking.converter.entity;

import com.baomidou.mybatisplus.annotation.*;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.wolfking.converter.dropdown.ParameterDropDown;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

@Data
@TableName("sql_define_param")
public class SqlDefineParam {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /**
     * 定义的key
     */
    @TableField("define_key")
    private String defineKey;

    /**
     * 参数名
     */
    @TableField("param_name")
    private String paramName;

    /**
     * 参数类型
     */
    @TableField("param_type")
    private String paramType;

    /**
     * 参数描述
     */
    @TableField("param_describe")
    private String paramDescribe;

    /**
     * 类型转换器
     */
    @TableField
    private String converter;
    /**
     * 格式，主要是时间参数
     */
    @TableField
    private String format;

    /**
     * 参数是否必须
     */
    @TableField
    private Boolean required;

    /**
     * 是否是pageNum
     */
    @TableField("page_num")
    private Boolean pageNum;

    /**
     * 是否是 pageSize
     */
    @TableField("page_size")
    private Boolean pageSize;

    /**
     * 默认值
     */
    @TableField("default_value")
    private String defaultValue;

    /**
     * 参数的表达式，做替换
     */
    @TableField("expression")
    private String expression;
    /**
     * 创建时间
     */
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private Date createTime;
    /**
     * 修改时间
     */
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

    /**
     * 版本号
     */
    @Version
    @TableField(value = "version", fill = FieldFill.INSERT)
    private Integer version;

    /**
     * 排序
     */
    @TableField("sort")
    private Integer sort;

    /**
     * 下拉选项
     */
    @TableField("drop_down")
    private String dropDown;


    @TableField("drop_down_class")
    private String dropDownClass;


    /**
     * 是否是下拉框
     */
    @TableField(exist = false)
    private boolean dropDownB = false;

    /**
     * 下拉框的值
     */
    @TableField(exist = false)
    private Map<String, String> dropDownMap = Maps.newHashMap();

    /**
     * 转换器转换后的值
     */
    @TableField(exist = false)
    private Object value;

    /**
     * base64解码
     *
     * @return 解码的SQL
     */
    public String getExpressionBase64Decode() {
        if (StringUtils.isNotBlank(this.expression)) {
            try {
                return new String(Base64.getDecoder().decode(this.expression), StandardCharsets.UTF_8);
            } catch (Exception e) {
                return expression;
            }
        } else {
            return "";
        }
    }

    public void assemblyDropDownMap() {
        try {
            if (StringUtils.isNotBlank(dropDownClass)) {
                ParameterDropDown parameterDropDown;
                try {
                    if (StringUtils.isBlank(dropDown)) {
                        parameterDropDown = (ParameterDropDown) Class.forName(dropDownClass).newInstance();
                    } else {
                        parameterDropDown = (ParameterDropDown) Class.forName(dropDownClass).getDeclaredConstructor(String.class).newInstance(dropDown.trim());
                    }
                } catch (Exception e) {
                    try {
                        parameterDropDown = (ParameterDropDown) Class.forName(dropDownClass).newInstance();
                    } catch (Exception ee) {
                        throw new RuntimeException(e);
                    }
                }
                dropDownB = true;
                dropDownMap = parameterDropDown.buildParameterDropDown();
            } else if (StringUtils.isNotBlank(dropDown)) {
                dropDownMap = new Gson().fromJson(dropDown, new TypeToken<TreeMap<String, String>>() {
                }.getType());
                if (dropDownMap.size() > 0) {
                    dropDownB = true;
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
